import java.util.ArrayList;
import java.util.Iterator;

public class genericity {
    public static void main(String[] args) {
    /*
    泛型是jdk5以后出现的，用于解决安全问题，是一个类型安全机制
        可以在编译时检查数据类型
    注意：泛型只能是引用类型
     */

        //没有泛型时候，集合怎么储存数据？
        ArrayList list = new ArrayList();
        //添加任意类型的数据
        list.add("aaa");
        list.add(1);
        list.add(true);
        //遍历集合
        Iterator it = list.iterator();
        while (it.hasNext()) {
            //取出元素
            Object obj = it.next();
            //多态的弊端是无法调用子类特有的方法
            // obj.length()
            //转型后其他类型的数据就输出不了了
            //String s = (String)obj;
            //System.out.println(s);
            System.out.println(obj);
        }

     /*通过这个例子我们知道集合里面存放数据的数组类型是Object，
     而泛型只是在加入元素的时候进行类型检查，取出元素的时候不需要转型
      */


     /*泛型的三种使用方式：
     1.泛型类     （集合的实现类都是，如ArrayList）
     2.泛型接口   （集合的接口都是，如collection,List）
     3.泛型方法   （集合的方法都是，如add()）
      */
        //泛型类的使用
        //当一个类中，某个变量的数据类型不确定，可以用泛型来定义
        //定义泛型类的格式：修饰符 class 类名<泛型变量>{ }
        class MyGenericity<T> {
            //成员变量
            private T t;

            //构造方法
            public MyGenericity(T t) {
                this.t = t;
            }

            //成员方法
            public T getT() {
                return t;
            }

            public void setT(T t) {

            }

            //泛型方法的使用
            //定义泛型方法的格式：修饰符 <泛型变量> 返回值类型 方法名(泛型变量 参数名){ }
            public <T> void show(T t) {
                System.out.println(t);
            }
        }


            //泛型接口的使用
            //定义泛型接口的格式：修饰符 interface 接口名<泛型变量>{ }
            interface MyGenericityInterface<T> {
                public abstract void show(T t);
            }

            /*
            指定泛型类型使用大写字母表示，为了提高代码的可读性，可以使用有意义的字母，常用的字母如下。
            （1）E（Element）常用于Java的集合，如List、Set、Iterator。
            （2）K、V（Key、Value）常用于Map的键 - 值对。
            （3）N（Number）表示数字。
            （4）T（Type）表示类型，如String、Integer等。
             */

    }
}